import { WetAirPointStateBase } from "./base";
import { IWetAirPoint } from "../types";

/** 湿空气状态点类，继承于基类，根据含湿量构造
 *
 */
export class WetAirStateByAbsHum extends WetAirPointStateBase {
  constructor(dbTemp: number, absHum: number, press = Constant.PRESSURE) {
    super(dbTemp, press);
    this.absHum = absHum;
  }

  /** 含湿量；单位：g/Kg */
  absHum: number;

  wetAirPoint() {
    const airPoint: IWetAirPoint = {
      dbTemp: this.dbTemp,
      absHum: this.absHum,
      airEnth: this.airEnth,
      relHum: this.relHum,
      wbTemp: this.wbTemp,
      dpTemp: this.dpTemp,
      density: this.density,
      SubPress: this.subPress,
      press: this.press,
    };
    return airPoint;
  }

  /** 焓值；单位：Kj/Kg；计算属性 */
  get airEnth() {
    return WetAirPointStateBase.computedEnth(this.dbTemp, this.absHum);
  }

  /** 相对湿度；单位：%；计算属性 */
  get relHum() {
    return this.absHum / this.saturationAbsHum;
  }

  /** 水蒸气分压；单位：Pa；计算属性*/
  get subPress() {
    return this.saturationSubPre * this.relHum;
  }

  /** 露点温度；单位：℃；计算属性  */
  get dpTemp() {
    return WetAirPointStateBase.computedDpTemp(this.dbTemp, this.subPress);
  }

  /** 湿球温度；单位：℃；计算属性  */
  get wbTemp() {
    return this.calculateWtTempWithEnth(this.airEnth);
  }

  /** 空气密度；单位：m3/Kg；计算属性 */
  get density() {
    return WetAirPointStateBase.computedDensity(
      this.dbTemp,
      this.subPress,
      this.press
    );
  }
}

/**  湿空气状态点类，继承于基类，根据相对湿度构造
 *
 */
export class WetAirStateByRelHum extends WetAirPointStateBase {
  constructor(dbTemp: number, relHum: number, press = Constant.PRESSURE) {
    super(dbTemp, press);
    if (relHum > 0 && relHum <= 1) {
      this.relHum = relHum;
    } else if (relHum > 1 && relHum <= 100) {
      this.relHum = relHum / 100;
    } else throw new Error(Constant.ArgumentOutOfRange);
  }

  /** 相对湿度；0~1的小数*/
  relHum: number;

  /** 水蒸气分压；单位：Pa；计算属性*/
  get subPress() {
    return this.saturationSubPre * this.relHum;
  }

  /** 含湿量；单位：g/Kg；计算属性 */
  get absHum() {
    return this.relHum * this.saturationAbsHum;
  }

  /** 焓值；单位：Kj/Kg；计算属性 */
  get airEnth() {
    return WetAirPointStateBase.computedEnth(this.dbTemp, this.absHum);
  }

  /** 露点温度；单位：℃；计算属性  */
  get dpTemp() {
    return WetAirPointStateBase.computedDpTemp(this.dbTemp, this.subPress);
  }

  /** 湿球温度；单位：℃；计算属性  */
  get wbTemp() {
    return this.calculateWtTempWithEnth(this.airEnth);
  }

  /** 空气密度；单位：m3/Kg；计算属性 */
  get density() {
    return WetAirPointStateBase.computedDensity(
      this.dbTemp,
      this.subPress,
      this.press
    );
  }

  /** 求湿空气状态点方法
   *
   * @returns
   */
  wetAirPoint() {
    const airPoint: IWetAirPoint = {
      dbTemp: this.dbTemp,
      absHum: this.absHum,
      airEnth: this.airEnth,
      relHum: this.relHum,
      wbTemp: this.wbTemp,
      dpTemp: this.dpTemp,
      density: this.density,
      SubPress: this.subPress,
      press: this.press,
    };
    return airPoint;
  }
}

/** 湿空气状态点类，继承于基类，根据湿球温度构造
 *
 */
export class WetAirStateByWbTemp extends WetAirPointStateBase {
  constructor(dbTemp: number, wbTemp: number, press = Constant.PRESSURE) {
    super(dbTemp, press);
    if (wbTemp > dbTemp) throw new Error(Constant.ArgumentOutOfRange);
    this.wbTemp = wbTemp;
  }

  /** 湿球温度；单位：℃*/
  wbTemp: number;

  /** 含湿量；单位：g/Kg；计算属性 */
  get absHum() {
    const subPress = this.calculateVaporSaturationPressure(this.wbTemp);
    const hum = this.calculateHumidity(subPress);
    return WetAirPointStateBase.computedAbsHum(this.dbTemp, this.wbTemp, hum);
  }

  /** 焓值；单位：Kj/Kg；计算属性 */
  get airEnth() {
    return WetAirPointStateBase.computedEnth(this.dbTemp, this.absHum);
  }

  /** 露点温度；单位：℃；计算属性  */
  get dpTemp() {
    return WetAirPointStateBase.computedDpTemp(this.dbTemp, this.subPress);
  }

  /** 相对湿度；单位：%；计算属性 */
  get relHum() {
    return this.absHum / this.saturationAbsHum;
  }

  /** 水蒸气分压；单位：Pa；计算属性*/
  get subPress() {
    return this.saturationSubPre * this.relHum;
  }

  /** 空气密度；单位：m3/Kg；计算属性 */
  get density() {
    return WetAirPointStateBase.computedDensity(
      this.dbTemp,
      this.subPress,
      this.press
    );
  }

  /** 求湿空气状态点方法
   *
   * @returns
   */
  wetAirPoint() {
    const airPoint: IWetAirPoint = {
      dbTemp: this.dbTemp,
      absHum: this.absHum,
      airEnth: this.airEnth,
      relHum: this.relHum,
      wbTemp: this.wbTemp,
      dpTemp: this.dpTemp,
      density: this.density,
      SubPress: this.subPress,
      press: this.press,
    };
    return airPoint;
  }
}
